package antrace;

public class DiggableGameLayer extends AbstractGameLayer {

	public static final int TUNNEL = 0;
	public static final int EARTH = 1;
	public static final int STONE = 6;
	public static int blockWidth = 36;
		
	private int blockCounter;
	private int level;
	private AntSprite sprite;
	
	private byte doOnce = 0;
	
	public DiggableGameLayer(AntSprite sprite) {
		super(blockWidth*3, 12,  AntRace.midlet.loadImage("/images/tiles/diggableTiles.png").image, 20, 20);	
		this.sprite = sprite;

		level = 1;

		BlockGenerator.getInstance().selectNewBlock(level);
		this.createTiledLayerFromArray(BlockGenerator.getInstance().getDiggableArray(), blockWidth);
		
		this.setPosition(0, 80);
	}
	
	public void collide(AntSprite sprite) {
		if (!sprite.isDead()) {
			// == Kollition med sten ===================
			if(isStone(getCurrentCol(sprite), getCurrentRow(sprite))) {
				stoneCollision();
			}
			// == Gå eller gräva     ====================
			else {
				digCollision();
			}
		}
	}
	
	private void stoneCollision(){
		sprite.setVelocity(0);
		sprite.setLockedDirection(sprite.getDirection());
	}
	
	private void digCollision(){
		
		if ( isTunnel(getCurrentCol(sprite), getCurrentRow(sprite)) ) {
			sprite.setState(AntSprite.STATE_WALKING);
		}			
		else {
			sprite.setState(AntSprite.STATE_DIGGING);
		}
		
		int difX = sprite.getRefPixelX() % 20;
		int difY = sprite.getRefPixelY() % 20;

		switch( sprite.getDirection() ) {
		case AntSprite.DIRECTION_RIGHT:
			if(difX >= 18) {
				dig(sprite);
			}
			break;
		case AntSprite.DIRECTION_DOWN:
			if(difY >= 18) {
				dig(sprite);
			}
			break;
		case AntSprite.DIRECTION_LEFT:
			if(difX <= 1) {
				dig(sprite);
			}
			break;
		case AntSprite.DIRECTION_UP:
			if(difY <= 1) {
				dig(sprite);
			}
			break;
		}
	}

	/**
	 * Kolla om en viss ruta vi är på är en tunnel eller ej
	 * @return true om det är en tunnel, annars false
	 */
	private boolean isTunnel(int column, int row) {

		return getCell(column, row) == TUNNEL;
	}
	
	private boolean isStone(int column, int row) {
		return getCell(column, row) == STONE;
	}
	
	private void dig(AntSprite sprite) {
		setCell(getCurrentCol(sprite), getCurrentRow(sprite), 0);

		if(getCell(getCurrentCol(sprite), getCurrentRow(sprite)) == 0) {
			sprite.setState(AntSprite.STATE_WALKING);
		}
	}

	public void reset() {
		this.setPosition(0, 80);
	}

	public void update() {
		if( sprite.getWorldX() % blockWidth*20 < blockWidth*20/2 ) { 
			if(sprite.getWorldX() > blockWidth*20/2 && doOnce == 0){
				//lägg till andra blocket
				BlockGenerator.getInstance().selectNewBlock(level);
				this.createTiledLayerFromArray(BlockGenerator.getInstance().getDiggableArray(), blockWidth, blockWidth);
				doOnce++;
			}
			else if(sprite.getWorldX() > blockWidth*20 && doOnce == 1){
				//lägg till tredje blocket
				BlockGenerator.getInstance().selectNewBlock(level);
				this.createTiledLayerFromArray(BlockGenerator.getInstance().getDiggableArray(), blockWidth, blockWidth*2);
				doOnce++;
			}
			
			if(this.getX() < -1.5*blockWidth*20){
				BlockGenerator.getInstance().selectNewBlock(level);
				this.moveLayerBlocks(BlockGenerator.getInstance().getDiggableArray(), blockWidth);
				this.createTiledLayerFromArray(BlockGenerator.getInstance().getDiggableArray(), blockWidth, blockWidth*2);
				sprite.setWorldX(sprite.getWorldX()-36*20);
				blockCounter++;
			}
			
		}
		
		// Anger vilket level du är på, beroende på hur många blcok som genererats
		switch (blockCounter){
		case 2:
			level = 2;
			//AntRace.midlet.println("Level 2");
			break;
		case 4:
			level = 3;
			//AntRace.midlet.println("Level 3");
			break;
		case 6:
			level = 4;
			//AntRace.midlet.println("Level 4");
			break; 
		case 8:
			level = 5;
			//AntRace.midlet.println("Level 5");
			break;
		}
		
	}

	/**
	 * För en position i jorden, kolla tilesen intill  och returnera deras värden
	 * @param column kolumnposition där man står
	 * @param row radposition där man står
	 * @return array med vad som finns i de fyra intilliggande tilesen.
	 *   0
	 * 3 + 1
	 *   2
	 */
	public int[] getGridEnvironment(int column, int row) {
		// TODO implementera den här...

		int[] environment = new int[4];
		int[] environmentIndexRow = {-1, 0, 1, 0};
		int[] environmentIndexCol = {0, 1, 0, -1};

		for (int i = 0 ; i < 4 ; i++) {
			try {
				environment[i] = getCell(column+environmentIndexCol[i], row+environmentIndexRow[i]);
				if (environment[i] > 1) {
					environment[i] = 1;
				}
			}
			catch (Exception e) {
//				System.out.println("Indexering utanför lagret!");
				environment[i] = EARTH;
			}
		}

		// invertera environment, då 1 = tunnel i tunglagret
		for (int i = 0 ; i < 4 ; i++) {
			if (environment[i] == 1) {
				environment[i] = 0;
			}
			else {
				environment[i] = 1;
			}
		}
		
		return environment;
	}

	/**
	 * För att tungan skall veta vilka positioner i TiledLayers 
	 * första kolumn i bild som är tunnlar, kolla detta här och
	 * returnera index för de rader som är tunnlar.
	 * Denna metod körs varje gång tungan skickas iväg.
	 * @return array med radindex för alla positioner som är tunnlar
	 * i första kolumnen i bild.
	 */
	public int[] getStartColumn() {
		int startColumn = -this.getX() / 20;
		//System.out.println("Startkolumn: " +startColumn);
		if  (startColumn < 0) {
			startColumn = 0;
		}
		int[] column = new int[12];

		int noOfTunnels = 0;
		int[] rows = new int[12];
		for (int i = 0; i < column.length; i++) {
			if (getCell(startColumn, i) == 0) {
				rows[noOfTunnels] = i;
				noOfTunnels++;
			}
		}
		int[] tunnels = new int[noOfTunnels];
		for (int i = 0; i < noOfTunnels; i++) {
			tunnels[i] = rows[i];
		}

				//System.out.print("Tunnels: ");
				for (int i = 0; i < tunnels.length; i++) {
					//System.out.print(tunnels[i]+", ");
				}
				//System.out.println();

		return tunnels;
	}

}


